<?php 
/*
 * @Descripttion: 同步政府接口
 * @version: v1
 * @Author: Terry
 * @Date: 2020-09-15 16:27:31
 * @LastEditors: Terry
 * @LastEditTime: 2024-10-26 13:58:42
 */
namespace app\BI\extend\components;

use think\facade\Db;

class ConfinedSpace{

    protected $tableName;
    protected $prjCode;
    /**
     * @description: 构造函数，获取项目的编码
     * @Author: Terry
     * @Date: 2022-04-20 19:25:46
     * @param {*} $prjCode 项目唯一码
     */    
    public function __construct(string $prjCode){
        $this->prjCode = $prjCode;
        $this->tableName = 'confinedSpace_gasData_'.trim($prjCode);
    }

    public function weather(){
        $prjCode = $this->prjCode;
        $province = '香港';
        $city = '香港';
        $county = '';
        $url = "https://wis.qq.com/weather/common?source=pc&weather_type=observe&province={$province}&city={$city}&county={$county}";
        $result = getCurl($url);
        if(!isset($result)||$result['status']!=200 ){
            return [
                'degree'=>'0',
                'weather'=>'晴',
                'weatherCode'=>'00',
                'windDirection'=>'微风',
                'humidity'=>'0',
            ];
        }
        $urls = [
            '00'=>env('oss.url').'/asset/sunny.png',
            '01'=>env('oss.url').'/asset/cloudy.png',
            '02'=>env('oss.url').'/asset/overcast.png',
            '07'=>env('oss.url').'/asset/showers.png',
            '04'=>env('oss.url').'/asset/rain.png',
            '05'=>env('oss.url').'/asset/thunderstorm.png',
        ];
        $observe =$result['data']['observe'];
        return [
            'degree'=>$observe['degree'],
            'humidity'=>$observe['humidity'],
            'weather'=>$observe['weather'],
            'weatherCode'=>$observe['weather_code'],
            'windDirection'=>$observe['wind_direction_name'],
            'iconUrl'=>$urls[$observe['weather_code']],
        ];
    }
    /**
     * @Description: 获取预警信息
     * @Author: Terry
     * @Date: 2024-10-22 18:31:13
     */    
    public function notice(){
        $notice= DB::table('platform_projectWarn')
        ->where([
            'module'=>'confinedSpace',
            'projectCode'=>$this->prjCode,
            'isHandled'=>0,
        ])->field(['correlationName as name','description','level','inDate'])
        ->order('id desc')
        ->select();
       return $notice;
    }
    /**
     * @Description: 获取历史趋势
     * @Author: Terry
     * @Date: 2024-10-22 10:35:11
     */
    public function  trend($range=[]){
        
        if($range){
            $startTimestamp = strtotime($range[0]);
            $endTimestamp = strtotime($range[1]);
        }
        if(!$range || !$startTimestamp || !$endTimestamp){
            $range =[date('Y-m-d H:i:s', strtotime('-12 hours')),date('Y-m-d H:i:s')];
        }
        $field = $this->getHourlyIntervals($range);
        
        try {
            $result = Db::table($this->tableName)
            ->alias('g2')
            ->field([
                Db::raw("DATE_FORMAT(g2.inDate, '%H') AS hour"),
                Db::raw('MAX(g2.O2) AS O2'),
                Db::raw('MAX(g2.CH4) AS CH4'),
                Db::raw('MAX(g2.CO) AS CO'),
                Db::raw('MAX(g2.H2S) AS H2S')
            ])
            ->join('confinedSpace_gas g', 'g.uuid = g2.gasUuid') // 添加JOIN条件
            ->where('g.isDelete', 0)                      // 确保设备未被删除
            ->where('g.projectCode', $this->prjCode)        // 添加projectCode条件
            ->where('g2.inDate', 'between',$range ) // 获取最近12小时的数据
            ->group('hour')
            ->order('hour', 'desc')
            ->select()->toArray();
        } catch (\Throwable $th) {
            dd($th->getMessage());
            $result = [];
        }
 
        // 在 $data 中添加基础值
        foreach ($field as $hour) {
            $initialValues = [
                "O2" => 0,
                "CH4" => 0,
                "CO" => 0,
                "H2S" => 0
            ];
            // 检查结果数组中是否有匹配的小时
            foreach ($result as $item) {
                if ($item['hour'] === $hour) {
                    unset($item['hour']);
                    $initialValues = array_merge($initialValues, $item);
                }
            }

            // 将每个小时的结果添加到 $data 中
            $data[] = $initialValues;
        }
        return compact('field','data');
    }

    public function getHourlyIntervals($range){
        // 获取起始时间和结束时间的时间戳
        $startTimestamp = strtotime($range[0]);
        $endTimestamp = strtotime($range[1]);

        // 初始化一个数组以存放小时
        $hours = [];

        // 循环从开始时间到结束时间
        for ($timestamp = $startTimestamp; $timestamp <= $endTimestamp; $timestamp += 3600) {
            $hours[] = date('H', $timestamp); // 获取小时，格式为 HH
        }
        return $hours;
    }
    public function progressFrom(){
        $table = "confinedSpace_gasData_{$this->prjCode}";
        try {
            $subQuery = Db::table($table)
            ->field('gasUuid, MAX(inDate) AS latestDate')
            ->group('gasUuid')
            ->buildSql(false); // 不添加别名，因为我们将在JOIN中指定别名
             // 主查询：获取最大气体值
            $result = Db::query("
                SELECT MAX(O2) AS O2, MAX(CH4) AS CH4, MAX(CO) AS CO, MAX(H2S) AS H2S
                FROM (
                    SELECT g2.O2, g2.CH4, g2.CO, g2.H2S
                    FROM {$table} g2
                    JOIN ({$subQuery}) g1 ON g2.gasUuid = g1.gasUuid AND g2.inDate = g1.latestDate
                    JOIN confinedSpace_gas g ON g.uuid = g2.gasUuid
                    WHERE g.projectCode = '{$this->prjCode}'
                    AND g.isDelete = 0
                ) latestData
            ");
        } catch (\Throwable $th) {
            $result = [
                [
                    "O2" => 0,
                    "CH4" => 0,
                    "CO" => 0,
                    "H2S" => 0
                ],
            ];
        }
        
        $rules = DB::table('platform_projectWarnSetting')->where([
            'module'=>'confinedSpace',
            'projectCode'=>$this->prjCode
        ])->value('rule');
        
        if(!$rules){
            $rules = '[{"type":"lastHeartDate","isEnabled":1,"alertInterval":86400,"rule":{"normal":"<= 86400","warn":"> 86400 && <= 86500","danger":"> 86500"}},{"type":"O2","isEnabled":1,"alertInterval":1440,"rule":{"normal":">= 20","warn":"> 20 && < 15","danger":"<= 15"}},{"type":"H2S","isEnabled":1,"alertInterval":1440,"rule":{"normal":"<= 35","warn":"> 35 && < 40","danger":">= 40"}},{"type":"H2S","isEnabled":1,"alertInterval":1440,"rule":{"normal":"<= 7","warn":"> 7 && < 15","danger":">= 15"}},{"type":"CO","isEnabled":1,"alertInterval":1440,"rule":{"normal":"<= 37","warn":"> 37 && < 75","danger":">= 75"}},{"type":"CH4","isEnabled":1,"alertInterval":1440,"rule":{"normal":"<= 7","warn":"> 7 && < 18","danger":">= 18"}}]';
        }
        $rules = json_decode($rules,true);
        $data = [];
        foreach ($result[0] as $key => $value) {
            $data[$key] = $value ?? 0 ;
        }

        // 初始化结果数组
        $result = [];
        // 遍历规则数组
        foreach ($rules as $rule) {
            $type = $rule['type'];
            // 只处理存在的传感器数据
            if (isset($data[$type])) {
                $dataValue = $data[$type];
                $percentage = 0; // 默认百分比为0
                // 特殊处理 CH4 和 CO 的百分比
                if ($type === 'CH4'|| $type === 'CO') {
                    preg_match('/(>=|<=|>|<|=)\s*(\d+)/', $rule['rule']['danger'], $matches);
                    $dangerValue = end($matches);
                    $percentage = ($dataValue / $dangerValue) * 100;
                } else{
                    $percentage = $dataValue;
                }
                // 组装结果
                $result[$type] = [
                    'data'=> $dataValue,
                    'rule' => $rule['rule']['normal'] . ' && ' . $rule['rule']['danger'], // 这里使用二级预警规则作为示例
                    'percentage' => round($percentage,2)
                ];
            }
        }
        return $result;
    }

    /**
     * @Description: 获取设备总数
     * @Author: Terry
     * @Date: 2024-10-21 22:58:05
     */
    public function online(){
    // 查询数据
        $result = Db::table('confinedSpace_gas')
        ->where([
            'projectCode'=>$this->prjCode,
            'isDelete'=>0,
            'level'=>1,
        ])->field([
            DB::raw('SUM(CASE WHEN connection = 1 THEN 1 ELSE 0 END) AS online'), // 在线设备数
            DB::raw('SUM(CASE WHEN connection = 0 THEN 1 ELSE 0 END) AS offline'), // 离线设备数
        ])->find();

        foreach ($result as &$value) {
            $value = $value ?? 0;
        }
        
        $list = Db::table('confinedSpace_gas')
        ->where([
            'projectCode'=>$this->prjCode,
            'isDelete'=>0,
            'level'=>1,
        ])->field(['name','connection'])
        ->select();
        
        if (!$result) {
            return [
                'online' => 0,
                'offline' => 0,
                'list'=>[],
            ];
        } 

        $result['list'] = $list;
        return $result;
    }
    
}
?>